using Agron.Services.Contracts;

using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.ServiceModel;


namespace Agron.Services.Broadcasting
{
    /// <summary>
    /// Implementation of the <see cref="IBroadcastingServiceEvents"/> contract.
    /// </summary>
    public class BroadcastingServiceEvents : IBroadcastingServiceEvents
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="BroadcastingServiceEvents"/> class.
        /// </summary>
        public BroadcastingServiceEvents() { }

        /// <summary>
        /// Fires when the mouse move in the host.
        /// </summary>
        /// <param name="userId">A <see cref="Guid"/> that contains the user id of the user logged on the service host.</param>
        /// <param name="displayName">A <see cref="String"/> that contains the display name of the user logged on the service host.</param>
        /// <param name="x">A <see cref="Int32"/> that contains the x-coordinate of the new mouse position.</param>
        /// <param name="y">A <see cref="Int32"/> that contains the y-coordinate of the new mouse position.</param>
        public void MouseMove(Guid userId, string displayName, int x, int y)
        {
            IntPtr deviceHandle = NativeMethods.GetDC(IntPtr.Zero);

            using (Graphics graphics = Graphics.FromHdc(deviceHandle))
            {
                graphics.DrawImage(Properties.Resources.PointerIcon, x, y);
                
                using (Font font = new Font(new FontFamily("Verdana"), 9f, FontStyle.Regular, GraphicsUnit.Point))
                {
                    graphics.DrawString(displayName, font, SystemBrushes.WindowText, x + Properties.Resources.PointerIcon.Width, y);
                }
            }
        }

        /// <summary>
        /// Fires when the mouse's left button is down.
        /// </summary>
        /// <param name="userId">A <see cref="Guid"/> that contains the user id of the user logged on the service host.</param>
        /// <param name="displayName">A <see cref="String"/> that contains the display name of the user logged on the service host.</param>
        /// <param name="x">A <see cref="Int32"/> that contains the x-coordinate of the new mouse position.</param>
        /// <param name="y">A <see cref="Int32"/> that contains the y-coordinate of the new mouse position.</param>
        public void LeftButtonDown(Guid userId, string displayName, int x, int y)
        {
        }

        /// <summary>
        /// Fires when the mouse's left button goes up.
        /// </summary>
        /// <param name="userId">A <see cref="Guid"/> that contains the user id of the user logged on the service host.</param>
        /// <param name="displayName">A <see cref="String"/> that contains the display name of the user logged on the service host.</param>
        /// <param name="x">A <see cref="Int32"/> that contains the x-coordinate of the new mouse position.</param>
        /// <param name="y">A <see cref="Int32"/> that contains the y-coordinate of the new mouse position.</param>
        public void LeftButtonUp(Guid userId, string displayName, int x, int y)
        {
        }

        /// <summary>
        /// Fires when the mouse's wheel moves.
        /// </summary>
        /// <param name="userId">A <see cref="Guid"/> that contains the user id of the user logged on the service host.</param>
        /// <param name="displayName">A <see cref="String"/> that contains the display name of the user logged on the service host.</param>
        /// <param name="x">A <see cref="Int32"/> that contains the x-coordinate of the new mouse position.</param>
        /// <param name="y">A <see cref="Int32"/> that contains the y-coordinate of the new mouse position.</param>
        public void MouseWheel(Guid userId, string displayName, int x, int y)
        {
        }

        /// <summary>
        /// Fires when the mouse's right button goes down.
        /// </summary>
        /// <param name="userId">A <see cref="Guid"/> that contains the user id of the user logged on the service host.</param>
        /// <param name="displayName">A <see cref="String"/> that contains the display name of the user logged on the service host.</param>
        /// <param name="x">A <see cref="Int32"/> that contains the x-coordinate of the new mouse position.</param>
        /// <param name="y">A <see cref="Int32"/> that contains the y-coordinate of the new mouse position.</param>
        public void RightButtonDown(Guid userId, string displayName, int x, int y)
        {
        }

        /// <summary>
        /// Fires when the mouse's right button goes up.
        /// </summary>
        /// <param name="userId">A <see cref="Guid"/> that contains the user id of the user logged on the service host.</param>
        /// <param name="displayName">A <see cref="String"/> that contains the display name of the user logged on the service host.</param>
        /// <param name="x">A <see cref="Int32"/> that contains the x-coordinate of the new mouse position.</param>
        /// <param name="y">A <see cref="Int32"/> that contains the y-coordinate of the new mouse position.</param>
        public void RightButtonUp(Guid userId, string displayName, int x, int y)
        {
        }

        static class NativeMethods
        {
            /// <summary>
            /// The GetDC function retrieves a handle to a display device context (DC) for the client area of a specified window or for the entire screen. You can use the returned handle in subsequent GDI functions to draw in the DC.
            /// </summary>
            /// <param name="hWnd">A <see cref="IntPtr"/> that contains a handle to the window whose DC is to be retrieved. If this value is NULL, GetDC retrieves the DC for the entire screen.</param>
            /// <returns>
            /// If the function succeeds, the return value is a handle to the DC for the specified window's client area. If the function fails, the return value is NULL.
            /// </returns>
            [DllImport("user32.dll")]
            internal static extern IntPtr GetDC(IntPtr hWnd);
        }
    }
}
